package com.ybwh.springboot1.websocket.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ybwh.springboot1.websocket.server.packet.ImBaseRequestPacket;
import com.ybwh.springboot1.websocket.server.packet.ImCid;
import com.ybwh.springboot1.websocket.server.packet.ImHeartbeatPacket;
import com.ybwh.springboot1.websocket.server.packet.ImHeartbeatResPacket;
import com.ybwh.springboot1.websocket.server.packet.ImLoginPacket;
import com.ybwh.springboot1.websocket.server.packet.ImLoginResPacket;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by jack on 2017/10/25.
 */
/**
 * websocket的具体实现类
 */
@ServerEndpoint(value = "/imcp/shangxinweb/ws")
@Component
public class WebSocketServer {
	private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
	// 静态变量，用来记录当前在线连接数。
	private static AtomicLong onlineCount = new AtomicLong(0);
	private static ConcurrentHashMap<String,  Session> tokenSessionMap = new ConcurrentHashMap<>();
	private static ThreadLocal<String> tokenLocal = new ThreadLocal<>();
	

	/**
	 * 连接建立成功调用的方法
	 */
	@OnOpen
	public void onOpen(Session session, EndpointConfig config) {
		
		
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose() {
		String token = tokenLocal.get();
		tokenLocal.set(null);
		tokenSessionMap.remove(token);
		onlineCount.decrementAndGet();
	}

	/**
	 * 收到客户端消息后调用的方法
	 *
	 * @param message
	 *            客户端发送过来的消息
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		System.out.println("来自客户端的消息:" + message);
		try {
		 ImBaseRequestPacket requestPacket = JSON.parseObject(message, ImBaseRequestPacket.class);
	        int cid = requestPacket.getEntry().getCid();
	        switch (cid) {
            case ImCid.LOGIN_REQ:
                onLoginReq(message,session);
                break;
//            case ImCid.LOGOUT_RES:
//                onLoginOutReply(receivedData);
//                break;
            case ImCid.HEARTBEAT:
                onHeartbeatReq(message,session);
                break;
           }
	        
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}

	private void onHeartbeatReq(String message, Session session) throws IOException {
		ImHeartbeatPacket packet = JSON.parseObject(message, ImHeartbeatPacket.class);
		String json ="{\"ClientHeartBeat\":{\"info\":\"heartbeat from push channel\"},\"Entry\":{\"cid\":3001,\"clientType\":3,\"imid\":1002000000026515}}";
		ImHeartbeatResPacket resPacket = JSON.parseObject(json, ImHeartbeatResPacket.class);
		resPacket.setUniqueKey(packet.getEntry().getUniqueKey());
//		resPacket.setCid(packet.getEntry().getCid());
		
		session.getBasicRemote().sendText(JSON.toJSONString(resPacket));
	}

	private void onLoginReq(String message, Session session) throws IOException {
		ImLoginPacket packet = JSON.parseObject(message, ImLoginPacket.class);
		String json ="{\"cid\":1004,\"uniqueKey\":\"4b277ce3-c7d4-47a6-ae09-9105e8fe2555\",\"UserLoginRes\":{\"serverTime\":1543806160232,\"resultCode\":0,\"resultString\":\"login success\",\"onlineStatus\":1,\"userInfo\":{\"imid\":1002000000026515,\"status\":1,\"userName\":\"工作通知\",\"imageUrl\":\"https://test-ehr-fs-1257236099.cos.ap-beijing.myqcloud.com/im_notify/icon_work_informs@2x.png\"}}}";
		ImLoginResPacket resPacket = JSON.parseObject(json, ImLoginResPacket.class);
		resPacket.setUniqueKey(packet.getEntry().getUniqueKey());
		resPacket.getUserLoginRes().getUserInfo().setImid(packet.getEntry().getImid());
//		resPacket.setCid(packet.getEntry().getCid());
		
		String token =packet.getEntry().getImid()+"";
		tokenLocal.set(token);
		tokenSessionMap.put(token, session);
		
		session.getBasicRemote().sendText(JSON.toJSONString(resPacket));
		
	}

	/**
	 * 发生错误时调用
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		System.out.println("发生错误");
		error.printStackTrace();
		try {
			session.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}